<?php
/**
 * Short description for file
 *
 * Long description for file (if any)...
 *
 * LICENSE: LGPL
 *
 * @category   Sabai
 * @package    Sabai_Template
 * @copyright  Copyright (c) 2006 myWeb Japan (http://www.myweb.ne.jp/)
 * @license    http://opensource.org/licenses/lgpl-license.php GNU LGPL
 * @version    CVS: $Id: Default.php 239 2008-03-07 08:39:10Z mikhail.miguel $
 * @link
 * @since      File available since Release 0.1.5
*/

/**
 * Sabai_Template
 */
require 'Sabai/Template.php';
/**
 * Sabai_Template_Default_Helper
 */
require 'Sabai/Template/Default/Helper.php';

/**
 * Short description for class
 *
 * Long description for class (if any)...
 *
 * @category   Sabai
 * @package    Sabai_Template
 * @copyright  Copyright (c) 2006 myWeb Japan (http://www.myweb.ne.jp/)
 * @author     Kazumi Ono <onokazu@gmail.com>
 * @license    http://opensource.org/licenses/lgpl-license.php GNU LGPL
 * @version    CVS: $Id: Default.php 239 2008-03-07 08:39:10Z mikhail.miguel $
 * @link
 * @since      Class available since Release 0.1.5
 */
class Sabai_Template_Default extends Sabai_Template
{
    var $_templateDir;
    var $_helperDir;
    var $_helpers = array();
    var $_predefinedVars;

    /**
     * Constructor
     *
     * @param array $templateDir
     * @param array $helperDir
     * @return Sabai_Template_Default
     */
    function Sabai_Template_Default($templateDir, $helperDir = array(), $predefinedVars = array())
    {
        $this->setTemplateDir((array)$templateDir);
        $this->_helperDir = array(dirname(__FILE__) . '/Default/Helper');
        foreach ((array)$helperDir as $helper_dir) {
            $this->addHelperDir($helper_dir);
        }
        $this->_predefinedVars = $predefinedVars;
    }

    function setTemplateDir($templateDir)
    {
        $this->_templateDir  = $templateDir;
    }

    function addTemplateDir($templateDir)
    {
        array_unshift($this->_templateDir, $templateDir);
    }

    function getTemplatePath($file)
    {
        // if the file name contains "/", it's considered absolute path
        if (false !== strpos($file, '/')) {
            if (file_exists($path)) {
                return $path;
            }
            return false;
        }
        foreach ($this->_templateDir as $template_dir) {
            $path = $template_dir . '/' . $file;
            if (file_exists($path)) {
                return $path;
            }
        }
        return false;
    }

    function _doDisplay($__file, $__vars)
    {
        // predefined vars have the priority over user defined vars
        $__vars = array_merge($__vars, $this->_predefinedVars);
        extract($__vars, EXTR_REFS);
        include $__file;
    }

    /**
     * Adds another helper direcoty to those already set
     *
     * @param string $path
     */
    function addHelperDir($path)
    {
        array_unshift($this->_helperDir, $path);
    }

    /**
     * Executes a helper
     *
     * @param string $name
     * @return mixed
     */
    function helper($name)
    {
        $name = str_replace('.', '', $name);
        $name_lc = strtolower($name);
        if (!isset($this->_helpers[$name_lc])) {
            $class = 'Sabai_Template_Default_Helper_' . $name;
            if (!class_exists($class)) {
                foreach ($this->_helperDir as $helper_dir) {
                    $class_path = sprintf('%s/%s.php', $helper_dir, $name);
                    if (file_exists($class_path)) {
                        require_once $class_path;
                        break;
                    }
                }
            }
            $helper =& new $class();
            $this->_helpers[$name_lc] =& $helper;
        }
        $args = func_get_args();
        return call_user_func_array(array(&$this->_helpers[$name_lc], 'execute'), array_slice($args, 1));
    }
}

function link_to($linkText, $urlParts, $attributes = array())
{
    echo create_link_to($linkText, $urlParts, $attributes);
}

function link_to_remote($linkText, $update, $linkUrl, $ajaxUrl = null, $options = array(), $attributes = array())
{
    echo create_link_to_remote($linkText, $update, $linkUrl, $ajaxUrl, $options, $attributes);
}

function create_link_to($linkText, $urlParts, $attributes = array())
{
    $attr = array();
    foreach ($attributes as $k => $v) {
        $attr[] = sprintf(' %s="%s"', $k, str_replace('"', '&quot;', $v));
    }
    return sprintf('<a href="%s"%s>%s</a>', Sabai_URL::getByArray($urlParts), implode('', $attr), $linkText);
}

function create_link_to_remote($linkText, $update, $linkUrl, $ajaxUrl = null, $options = array(), $attributes = array())
{
    $ajaxUrl = !isset($ajaxUrl) ? $linkUrl : $ajaxUrl;
    $ajaxUrl['params'][SABAI_REQUEST_WEB_PARTIAL_PARAM] = 1;
    $html = array();
    $ajax_options[] = !empty($options['post']) ? "method:'post'" : "method:'get'";
    $toggle = $replace = '';
    if (!empty($options['toggle'])) {
        $attributes['id'] = $update . '-show';
        $toggle = sprintf("\$('%1\$s-show').hide(); \$('%1\$s-hide').show();", $update);
        $html[] = sprintf('<a href="" id="%1$s-hide" style="display:none;">%2$s</a>
<script type="text/javascript">
Event.observe("%1$s-hide", "click", function(evt) {
  Effect.toggle("%1$s", "blind");
  Event.stop(evt);
});
</script>', $update, $linkText);
        $ajax_options[] = sprintf("evalScripts:true, onLoading:function(req){\$('%1\$s').update('<div>Loading...</div>');}, onSuccess:function(req){\$('%1\$s').hide().update(req.responseText);
Effect.toggle('%1\$s', 'blind');}", $update);
    } else {
        $ajax_options[] = "evalScripts:true, onSuccess:function(req){\$('$update').update(req.responseText);}";
    }
    if ($failure = @$options['failure']) {
        $ajax_options[] = "onFailure:function(req){\$('$failure').update(req.responseText);}";
    }
    if (!empty($options['replace'])) {
        $replace = sprintf("this.up().update('%s');", $options['replace']);
    }
    $attributes['onclick'] = sprintf("
new Ajax.Request('%2\$s', {%3\$s});%4\$s%5\$s new Effect.ScrollTo('%1\$s', {offset:-20}); return false;", $update, Sabai_URL::getByArray($ajaxUrl), implode(', ', $ajax_options), $toggle, $replace);
    $html[] = create_link_to($linkText, $linkUrl, $attributes);
    return implode("\n", $html);
}

function select_to_remote($name, $value, $update, $options, $actionUrl, $submit, $formId = null, $ajaxUrl = null, $attributes = array())
{
    echo create_select_to_remote($name, $value, $update, $options, $actionUrl, $submit, $formId, $ajaxUrl, $attributes);
}

function create_select_to_remote($name, $value, $update, $options, $actionUrl, $submit, $formId = null, $ajaxUrl = null, $disableSelf = false, $attributes = array())
{
    $form_id = !isset($formId) ? md5(uniqid(rand(), true)) : h($formId);
    $ajaxUrl = !isset($ajaxUrl) ? $actionUrl : $ajaxUrl;
    $ajaxUrl['params'][SABAI_REQUEST_WEB_PARTIAL_PARAM] = 1;
    if ($disableSelf) {
        $onchange[] = sprintf("if (this.value == '%s') return;", $value);
    }
    $onchange[] = sprintf("
new Ajax.Request(
  '%2\$s',
  {onSuccess:function(req){\$('%1\$s').update(req.responseText);},
   method:'get',
   evalScripts:true,
   parameters:Form.serialize(\$('%3\$s'))
  });
new Effect.ScrollTo('%1\$s', {offset: -20});
return false;", $update, Sabai_URL::getByArray($ajaxUrl), $form_id);
    $html[] = sprintf('<form style="display:inline; margin:0; padding:0;" id="%4$s" method="get" action="%2$s"><select name="%1$s" onchange="%3$s">', h($name), Sabai_URL::getByArray($actionUrl), implode("\n", $onchange), $form_id);
    foreach (array_keys($options) as $v) {
        if ($v == $value) {
            $html[] = sprintf('<option value="%s" selected="selected">%s</option>', h($v), h($options[$v]));
        } else {
            $html[] = sprintf('<option value="%s">%s</option>', h($v), h($options[$v]));
        }
    }
    $html[] = sprintf('</select> <input id="%s-submit" type="submit" value="%s" />', $form_id, h($submit));
    foreach ((array)@$actionUrl['params'] as $param_k => $param_v) {
        $html[] = sprintf('<input type="hidden" name="%s" value="%s" />', h($param_k), h($param_v));
    }
    $html[] = sprintf('</form>
<script type="text/javascript">
$("%s-submit").hide();
</script>', $form_id);
    return implode("\n", $html);
}

function form_tag($method = 'post', $action = null, $attributes = array())
{
    $method = strcasecmp($method, 'get') == 0 ? 'get' : 'post';
    if (isset($action)) {
        $attributes['action'] = $action;
    }
    $attr = array();
    foreach ($attributes as $k => $v) {
        $attr[] = sprintf(' %s="%s"', $k, str_replace('"', '&quot;', $v));
    }
    printf('<form method="%s"%s>', $method, implode('', $attr));
}

function form_tag_end()
{
    print('</form>');
}

function link_to_toggle($toggle, $hidden = false, $hideText = '[-]', $showText = '[+]')
{
    // set display to none so that the toggle link will not show if JS disabled
    printf('<a href="" id="%s-toggle" style="display:none;">%s</a>', $toggle, $hidden ? $showText : $hideText);
    printf('<script type="text/javascript">
$("%1$s-toggle").show();
$("%1$s-toggle").observe("click", function(evt) {
  Effect.toggle("%1$s", "blind");
  Event.stop(evt);
  if ($("%1$s").visible()) {
    $("%1$s-toggle").update("%3$s");
  }else {
    $("%1$s-toggle").update("%2$s");
  }
});
</script>', $toggle, $hideText, $showText);
}

function link_to_hide_class($class, $hideText = '[-]', $showText = '[+]')
{
    // set display to none so that the toggle link will not show if JS disabled
    printf('<a href="" id="%1$s-hide" style="display:none;">%2$s</a>
<script type="text/javascript">
$("%1$s-hide").show();
$("%1$s-hide").observe("click", function(evt) {
  $$("div.%1$s").each(function(ele) {
    if (ele.visible()) {
      Effect.BlindUp(ele);
      $(ele.id + "-toggle").update("%3$s");
    }
  });
  Event.stop(evt);
});
</script>', $class, $hideText, $showText);
}

function link_to_show_class($class, $showText = '[+]', $hideText = '[-]')
{
    // set display to none so that the toggle link will not show if JS disabled
    printf('<a href="" id="%1$s-show" style="display:none;">%2$s</a>
<script type="text/javascript">
$("%1$s-show").show();
$("%1$s-show").observe("click", function(evt) {
  $$("div.%1$s").each(function(ele) {
    if (!ele.visible()) {
      Effect.BlindDown(ele);
      $(ele.id + "-toggle").update("%3$s");
    }
  });
  Event.stop(evt);
});
</script>', $class, $showText, $hideText);
}